package com.kili.mirco.spark_als.ref.factory;

import avro.shaded.com.google.common.base.Preconditions;
import com.kili.mirco.spark_als.exp.NoneBasicClassException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @date 19-6-3
 * @auther jackliang
 * @description TODO
 */
@Slf4j
public abstract class AbstractAlogrithmFactoy implements RecommendFactory {

    protected static ClassLoader MAIN_LOADER = ClassLoader.getSystemClassLoader();

    public static Map<String, Object> BEANS = Collections.synchronizedMap(new LinkedHashMap());


    public AbstractAlogrithmFactoy() {
        this(BEANS);
    }

    public AbstractAlogrithmFactoy(Map<String, Object> BEANS) {
        AbstractAlogrithmFactoy.BEANS = BEANS;
    }

    public void addBean(String name, Object bean) {
        BEANS.put(name, bean);
    }


    @Override
    public <T> T getBean(Class<T> var1) {
        Preconditions.checkNotNull(var1, "ClassLoader for Bean class is matched error");

        String var3 = this.getNameOfEnd(var1);

        if (this.containsBean(var3)) return (T) this.getBean(var3);

        T var2 = null;
        try {
            var2 = var1.newInstance();
        } catch (Exception e) {
            log.error("To be initialized Class is error", e);
            new NoneBasicClassException("Initialized error ! . Maybe the one didnt base class type .");
        }

        this.addBean(var3, var2);

        return var2;
    }

    private <T> String getNameOfEnd(Class<T> var1) {
        return org.apache.commons.lang3.StringUtils.uncapitalize(var1.getSimpleName());
    }


    @Override
    public Object getBean(String name) throws BeansException {
        String beanName = BeanFactoryUtils.transformedBeanName(name);
        Object bean = this.BEANS.get(beanName);
        return Optional.ofNullable(bean).orElseThrow(() ->
                new NoSuchBeanDefinitionException(
                        "Defined BEANS are [" +
                                StringUtils.
                                        collectionToCommaDelimitedString(
                                                BEANS.keySet()
                                        )
                                + "]")
        );

    }


    @Override
    public boolean containsBean(String var1) {
        return BEANS.containsKey(var1);
    }

}
